home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / nihcl-30.lha / nihcl-3.0 / lib / ArrayOb.c < prev    next >
C/C++ Source or Header  |  1990-05-19  |  6KB  |  274 lines

  1. /* ArrayOb.c -- member functions of class ArrayOb
  2.  
  3.     THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
  4.     "UNITED STATES GOVERNMENT WORK".  IT WAS WRITTEN AS A PART OF THE
  5.     AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE.  THIS MEANS IT
  6.     CANNOT BE COPYRIGHTED.  THIS SOFTWARE IS FREELY AVAILABLE TO THE
  7.     PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
  8.     RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
  9.  
  10. Author:
  11.     K. E. Gorlen
  12.     Bg. 12A, Rm. 2033
  13.     Computer Systems Laboratory
  14.     Division of Computer Research and Technology
  15.     National Institutes of Health
  16.     Bethesda, Maryland 20892
  17.     Phone: (301) 496-1111
  18.     uucp: uunet!nih-csl!kgorlen
  19.     Internet: kgorlen@alw.nih.gov
  20.     September, 1985
  21.  
  22. Function:
  23.     
  24. Member function definitions for class ArrayOb (Array of Object*).
  25. Objects of class ArrayOb are used in the implementations of several
  26. other Collection classes such as: Bag, Dictionary, Set, and
  27. OrderedCltn.  Note that the ArrayOb constructor initializes the array
  28. with pointers to the nil object.
  29.  
  30. $Log:    ArrayOb.c,v $
  31.  * Revision 3.0  90/05/20  00:18:54  kgorlen
  32.  * Release for 1st edition.
  33.  * 
  34. */
  35.  
  36. #include <libc.h>
  37. #include <malloc.h>
  38. #include "ArrayOb.h"
  39. #include "nihclIO.h"
  40.  
  41. #define    THIS    ArrayOb
  42. #define    BASE    Collection
  43. #define BASE_CLASSES BASE::desc()
  44. #define MEMBER_CLASSES
  45. #define VIRTUAL_BASE_CLASSES
  46.  
  47. DEFINE_CLASS(ArrayOb,1,"$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/lib/RCS/ArrayOb.c,v 3.0 90/05/20 00:18:54 kgorlen Rel $",NULL,NULL);
  48.  
  49. extern const int NIHCL_ALLOCSIZE,NIHCL_INDEXRANGE;
  50.  
  51. /*
  52. Note: we use malloc()/free() here instead of new/delete because
  53. we use realloc() to implement reSize().
  54. */
  55.  
  56. #define NEW(type,size)    ((type*)malloc(sizeof(type)*(size)))
  57.  
  58. inline void DELETE(Object** ptr) { free((char*)ptr); }
  59.  
  60. inline Object** REALLOC(Object** ptr, unsigned size)
  61. {
  62.     return (Object**)realloc((char*)ptr,sizeof(Object*)*size);
  63. }
  64.  
  65. ArrayOb::ArrayOb(unsigned size)
  66. {
  67.     sz = size;
  68.     if (sz==0) allocSizeErr();
  69.     v = NEW(Object*,sz);
  70.     register i = sz;
  71.     register Object** vp = v;
  72.     while (i--) *vp++ = nil;
  73. }
  74.     
  75. ArrayOb::ArrayOb(const ArrayOb& a)
  76. {
  77.     register i = a.sz;
  78.     sz = i;
  79.     v = NEW(Object*,i);
  80.     register Object** vp = v;
  81.     register Object** av = a.v;
  82.     while (i--) *vp++ = *av++;
  83. }
  84.  
  85. ArrayOb::~ArrayOb()    { DELETE(v); }
  86.  
  87. void ArrayOb::operator=(const ArrayOb& a)
  88. {
  89.     if (v != a.v) {
  90.         DELETE(v);
  91.         v = NEW(Object*,sz=a.sz);
  92.         register i = a.sz;
  93.         register Object** vp = v;
  94.         register Object** av = a.v;
  95.         while (i--) *vp++ = *av++;
  96.     }
  97. }
  98.  
  99. bool ArrayOb::operator==(const ArrayOb& a) const
  100. {
  101.     if (sz != a.sz) return NO;
  102.     register unsigned i = sz;
  103.     register Object** vp = v;
  104.     register Object** av = a.v;
  105.     while (i--) { if (!((*vp++)->isEqual(**av++))) return NO; }
  106.     return YES;
  107. }
  108.  
  109. Object*& ArrayOb::at(int i)            { return (*this)[i]; }
  110.  
  111. const Object *const& ArrayOb::at(int i) const    { return (*this)[i]; }
  112.  
  113. unsigned ArrayOb::capacity() const    { return sz; }
  114.     
  115. bool ArrayOb::isEqual(const Object& a) const
  116. {
  117.     return a.isSpecies(classDesc) && *this==castdown(a);
  118. }
  119.  
  120. const Class* ArrayOb::species() const { return &classDesc; }
  121.  
  122. void ArrayOb::reSize(unsigned newsize)
  123. {
  124.     if (newsize == 0) allocSizeErr();
  125.     v = REALLOC(v,newsize);
  126.     if (newsize > sz) {    // initialize new space to nil
  127.         Object** vp = &v[sz];
  128.         while (newsize > sz) {
  129.             *vp++ = nil;
  130.             sz++;
  131.         }
  132.     }
  133.     else sz = newsize;
  134. }
  135.  
  136. void ArrayOb::removeAll()
  137. {
  138.     register Object** vp = v;
  139.     register unsigned i = sz;
  140.     while (i--) *vp++ = nil;
  141. }
  142.  
  143. Collection& ArrayOb::addContentsTo(Collection& cltn) const
  144. {
  145.     register Object** vp = v;
  146.     register unsigned i = sz;
  147.     while (i--) cltn.add(**vp++);
  148.     return cltn;
  149. }
  150.  
  151. Object* ArrayOb::doNext(Iterator& pos) const
  152. {
  153.     if (pos.index < size()) return v[pos.index++];
  154.     return 0;
  155. }
  156.  
  157. void ArrayOb::deepenShallowCopy()
  158. {
  159.     BASE::deepenShallowCopy();
  160.     register i = sz;
  161.     register Object** vp = v;
  162.     while (i--) {
  163.         *vp = (*vp)->deepCopy();
  164.         vp++;
  165.     }
  166. }
  167.  
  168. unsigned ArrayOb::hash() const
  169. {
  170.     register unsigned h = sz;
  171.     register unsigned i = sz;
  172.     register Object** vp = v;
  173.     while (i--) h^=(*vp++)->hash();
  174.     return h;
  175. }
  176.  
  177. ArrayOb::ArrayOb(OIOin& strm)
  178. :
  179. #ifdef MI
  180.     Object(strm),
  181. #endif
  182.     BASE(strm)
  183. {
  184.     strm >> sz;
  185.     v = NEW(Object*,sz);
  186.     for (register unsigned i=0; i<sz; i++) v[i] = Object::readFrom(strm);
  187. }
  188.  
  189. void ArrayOb::storer(OIOout& strm) const
  190. {
  191.     BASE::storer(strm);
  192.     strm << sz;
  193.     for (register unsigned i=0; i<sz; i++) v[i]->storeOn(strm);
  194. }
  195.  
  196. unsigned ArrayOb::size() const    { return sz; }
  197.  
  198. static int compare_ob(const void* a, const void* b)
  199. {
  200.     return (*(const Object**)a)->compare(**(const Object**)b);
  201. }
  202.  
  203. void ArrayOb::sort()
  204. {
  205.     qsort(v,sz,sizeof(Object*),compare_ob);
  206. }
  207.  
  208. void ArrayOb::allocSizeErr() const
  209. {
  210.     setError(NIHCL_ALLOCSIZE,DEFAULT,this,className());
  211. }
  212.  
  213. void ArrayOb::indexRangeErr() const
  214. {
  215.     setError(NIHCL_INDEXRANGE,DEFAULT,this,className());
  216. }
  217.  
  218. ArrayOb::ArrayOb(OIOifd& fd)
  219. :
  220. #ifdef MI
  221.     Object(fd),
  222. #endif
  223.     BASE(fd)
  224. {
  225.     fd >> sz;
  226.     v = NEW(Object*,sz);
  227.     for (register unsigned i=0; i<sz; i++ )
  228.        v[i] = Object::readFrom(fd);
  229. }
  230.  
  231. void ArrayOb::storer(OIOofd& fd) const
  232. {
  233.     BASE::storer(fd);
  234.     fd << sz;
  235.     for (register unsigned i=0; i<sz; i++) 
  236.         v[i]->storeOn(fd);
  237. }
  238.  
  239. int ArrayOb::compare(const Object& arg) const
  240. // Compare two arrays of objects.  If *this > arg return >0,
  241. // *this == arg return 0, and if *this < arg return <0.
  242. {
  243.     assertArgSpecies(arg,classDesc,"compare");
  244.     const ArrayOb& a = castdown(arg);
  245.     for (int i=0; i<sz; i++) {
  246. // previous elements compared equal; longer ArrayOb is therefore larger
  247.         if (i == a.sz) return 1;
  248. // compare() != 0 at any element determines ordering
  249.         int val;
  250.         if ((val = v[i]->compare(*a.v[i])) != 0) return val;
  251.     }
  252. // all elements in this ArrayOb compare() equal to arg ArrayOb
  253.     if (sz == a.sz) return 0;
  254.     return -1;
  255. }
  256.  
  257. Object* ArrayOb::add(Object& ob)
  258. {
  259.     shouldNotImplement("add");
  260.     return &ob;
  261. }
  262.  
  263. unsigned ArrayOb::occurrencesOf(const Object&) const
  264. {
  265.     shouldNotImplement("occurrencesOf");
  266.     return 0;
  267. }
  268.  
  269. Object* ArrayOb::remove(const Object&)
  270. {
  271.     shouldNotImplement("remove");
  272.     return 0;
  273. }
  274.